((Metro, $) => {
    // biome-ignore lint/suspicious/noRedundantUseStrict: <explanation>
    "use strict";

    const participants = "[data-role-dropmenu], [data-role-dropdown]";
    const toggleImage = `<svg class="dropdown-caret" aria-hidden="true" width="16" height="16" viewBox="0 0 24 24"><path d="m14.83 11.29-4.24-4.24a1 1 0 1 0-1.42 1.41L12.71 12l-3.54 3.54a1 1 0 0 0 0 1.41 1 1 0 0 0 .71.29 1 1 0 0 0 .71-.29l4.24-4.24a1.002 1.002 0 0 0 0-1.42Z"></path></svg>`;

    let DropdownDefaultConfig = {
        dropdownDeferred: 0,
        dropFilter: null,
        toggleElement: null,
        noClose: false,
        openMode: "auto",
        openFunc: "show",
        closeFunc: "hide",
        height: "auto",
        stayOnClick: false,
        onDrop: Metro.noop,
        onUp: Metro.noop,
        onDropdownCreate: Metro.noop,
    };

    Metro.dropdownSetup = (options) => {
        DropdownDefaultConfig = $.extend({}, DropdownDefaultConfig, options);
    };

    if (typeof globalThis.metroDropdownSetup !== "undefined") {
        Metro.dropdownSetup(globalThis.metroDropdownSetup);
    }

    Metro.Component("dropdown", {
        init: function (options, elem) {
            this._super(elem, options, DropdownDefaultConfig, {
                toggle: null,
                displayOrigin: null,
                isOpen: false,
                level: 0,
                ready: false,
            });

            return this;
        },

        _create: function () {
            setTimeout(() => {
                const element = this.element;

                this._createStructure();
                this._createEvents();

                this._fireEvent("dropdown-create", {
                    element: element,
                });

                if (element.hasClass("open")) {
                    element.removeClass("open");
                    setTimeout(() => {
                        this.open(true);
                    }, 0);
                }

                this.ready = true;
            }, this.options.dropdownDeferred);
        },

        _toggle: function () {
            const element = this.element;
            let toggle = element.siblings(".menu-toggle, .dropdown-toggle, a");
            if (toggle.length === 0) {
                toggle = element.prev();
                if (toggle.length === 0) {
                    throw new Error("Menu toggle not found");
                }
            }
            return toggle[0];
        },

        _createStructure: function () {
            const element = this.element;
            const o = this.options;
            const level = element.parents("[data-role-dropdown]").length;
            let toggle;

            element.addClass("dropdown");

            if (o.openMode === "up") {
                element.addClass("drop-up");
            }
            if (o.openMode === "right") {
                element.addClass("drop-right");
            }
            if (o.openMode === "left") {
                element.addClass("drop-left");
            }
            if (o.openMode === "down") {
                element.addClass("drop-down");
            }

            toggle = o.toggleElement ? $(o.toggleElement) : $(this._toggle());
            if (toggle.length) {
                toggle.append(toggleImage);
            }

            this.displayOrigin = Metro.utils.getStyleOne(element, "display");

            if (o.height !== "auto") {
                element.css({
                    height: o.height,
                    "overflow-y": "auto",
                });
            }
            element.css("display", "none");

            this.toggle = toggle;
            this.level = level;
        },

        _createEvents: function () {
            const element = this.element;
            const o = this.options;
            const toggle = this.toggle;
            const parent = element.parent();

            toggle.on(Metro.events.click, (e) => {
                $(".active-container").removeClass("active-container");

                // parent.siblings(parent[0].tagName).removeClass("active-container");

                if (element.css("display") !== "none" && !element.hasClass("keep-open")) {
                    this.close(true, element);
                } else {
                    $(participants).each((_, el) => {
                        if (
                            !element.parents("[data-role-dropdown]").is(el) &&
                            !$(el).hasClass("keep-open") &&
                            $(el).css("display") !== "none"
                        ) {
                            if (!Metro.utils.isValue(o.dropFilter)) {
                                this.close(true, el);
                            } else {
                                if ($(el).closest(o.dropFilter).length > 0) {
                                    this.close(true, el);
                                }
                            }
                        }
                    });
                    if (element.hasClass("horizontal")) {
                        element.css({
                            visibility: "hidden",
                            display: "block",
                        });
                        let children_width = 0;
                        $.each(element.children("li"), function () {
                            children_width += $(this).outerWidth(true);
                        });

                        element.css({
                            visibility: "visible",
                            display: "none",
                        });
                        element.css("width", children_width + 2);
                    }
                    this.open(false, element);
                    parent.addClass("active-container");
                }
                e.preventDefault();
                e.stopPropagation();
            });

            if (o.noClose === true) {
                element.addClass("keep-open").on(Metro.events.click, (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                });
            }

            $(element)
                .find(".disabled")
                .on(Metro.events.click, (e) => {
                    e.preventDefault();
                    e.stopPropagation();
                });

            if (o.stayOnClick === true) {
                element.on(Metro.events.click, (e) => {
                    // e.preventDefault();
                    e.stopPropagation();
                });
            }
        },

        _close: function (el, immediate) {
            const _el = $(el);

            const dropdown = Metro.getPlugin(_el, "dropdown");

            if (!dropdown.ready) {
                return;
            }

            const toggle = dropdown.toggle;
            const options = dropdown.options;
            let func = options.closeFunc;

            if (toggle?.length) toggle.removeClass("active-toggle").removeClass("active-control");
            dropdown.element.parent().removeClass("active-container");

            if (immediate) {
                func = "hide";
            }

            _el[func](immediate ? 0 : 100, () => {
                dropdown._fireEvent("close");
                dropdown._fireEvent("up");

                if (options.openMode === "auto") {
                    dropdown.element.removeClass("drop-up drop-as-dialog");
                }
            });

            this.isOpen = false;
        },

        _open: function (el, immediate) {
            const dropdown = Metro.getPlugin(el, "dropdown");
            const options = dropdown.options;
            const func = options.openFunc;

            dropdown.toggle.addClass("active-toggle").addClass("active-control");
            dropdown.element.parent().addClass("active-container");

            dropdown.element[func](immediate ? 0 : 100, function () {
                const $el = $(this);
                const wOut = Metro.utils.viewportOutByWidth(this);
                const hOut = Metro.utils.viewportOutByHeight(this);

                if (options.openMode === "auto") {
                    if (hOut) {
                        $el.addClass("drop-up");
                    }
                    if (wOut) {
                        $el.addClass("place-right");
                    }

                    if (Metro.utils.viewportOut(this)) {
                        $el.removeClass("drop-up place-right").addClass("drop-as-dialog");
                    }
                }

                dropdown._fireEvent("open");
                dropdown._fireEvent("drop");
            });

            this.isOpen = true;
        },

        close: function (immediate, el) {
            this._close(el || this.element, immediate);
        },

        open: function (immediate, el) {
            this._open(el || this.element, immediate);
        },

        toggle: function () {
            if (this.isOpen) this.close();
            else this.open();
        },

        changeAttribute: (attr, val) => {},

        destroy: function () {
            this.toggle.off(Metro.events.click);
        },
    });

    $(document).on(Metro.events.click, () => {
        $(participants).each(function () {
            const el = $(this);

            if (el.hasClass("keep-open") || el.hasClass("stay-open") || el.hasClass("ignore-document-click")) return;

            const dd = Metro.getPlugin(el, "dropdown");
            const dm = Metro.getPlugin(el, "dropmenu");

            if (dd) {
                dd.close();
            }
            if (dm) {
                dm.close();
            }
        });
    });
})(Metro, Dom);
